using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using T.ServiceComponent.DataAccessEx.Core;
using MySql.Data.MySqlClient;
using System.Transactions;
using System.Data.Common;

namespace T.FAS.Runtime.DataAccess.UnitTest
{
    /// <summary>
    /// 测试MSDTC
    /// </summary>
    [TestClass]
    public class TestDACComponent
    {
        public const string mysqlConnStr = "data source=127.0.0.1;database=TFAS;user id=root;password=123456;port=3306;";   //AutoEnlist=false;
        public const string mssqlConnStr = "data source=127.0.0.1,1433;database=TMaster;user id=sa;password=T@t.cn;";
        public const string localmssql = "data source=127.0.0.1;database=TMaster;user id=sa;password=123;";
        public const string Configkey = "TTP.Database.TMasterRead.ConnectionString";

        /// <summary>
        /// 测试通过配置key访问DB
        /// </summary>
        [TestMethod]
        public void TestQuerySQL()
        {
            try
            { 
                var key = "TFAS_BUTest.Config.All";
                DataSet ds1;
                DataSet ds2;
                using (ITDatabase db = GetDatabaseByConfigkey(key))
                {
                    ds1 = db.ExecuteDataSet("select * from testdac_dept");
                }
                using (ITDatabase db = GetDatabaseByConfigkey(key))
                {
                    ds2 = db.ExecuteDataSet("select * from testdac_dept");
                } 
            }
            catch (Exception e)
            {

                throw;
            }
        }

        [TestMethod]
        public void TestMysql()
        {
            var sql = "select * from testdac_dept";
            try
            {
                using (MySqlConnection conn = new MySqlConnection(mysqlConnStr))
                {
                    //conn.Open();
                    MySqlCommand command = new MySqlCommand(sql, conn);
                    DataSet ds = new DataSet();
                    var adp = new MySqlDataAdapter(command);
                    adp.Fill(ds);
                    Console.WriteLine(ds);
                }

            }
            catch (Exception e)
            {

                throw e;
            }
        }

        [TestMethod]
        public void TestMSSQL()
        {  
            var sql = "select * from Test_BillDetail where price= @Param_DO_TableDetail_Attribute_DateTime_b64c3384f02a47adb50af7ddd7ad0f2a";
            try
            {
                var connstr = "data source=139.219.1.183,1433;database=TFAS_BUTest;user id=sa;password=T@t.cn;";
                using (SqlConnection conn = new SqlConnection(connstr))
                {
                    //conn.Open();
                    SqlCommand command = new SqlCommand(sql, conn);
                    command.Parameters.Add(new SqlParameter
                    {
                        ParameterName = "@Param_DO_TableDetail_Attribute_DateTime_b64c3384f02a47adb50af7ddd7ad0f2a",
                        Value = "1",
                    }) ;
                    DataSet ds = new DataSet();
                    var adp = new SqlDataAdapter(command);
                    adp.Fill(ds);
                    Console.WriteLine(ds);
                    Assert.IsTrue(ds.Tables[0].Rows.Count > 0);
                }

            }
            catch (Exception e)
            {

                throw e;
            }
        }

        /// <summary>
        /// 测试分布式事务
        /// </summary>
        [TestMethod]
        public void TestMSDTC_MSSQL_MSSQL()
        {
            //开启外部MSSQL事务
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    SqlConnection mssqlconn = new SqlConnection(mssqlConnStr);
                    mssqlconn.Open();
                    var mssqlDs = GetDataSet(mssqlconn, DBType.MSSQL, "Select top 10 * from ACM_ApplicationHost;");

                    SqlConnection mssqlconn2 = new SqlConnection(mssqlConnStr);
                    mssqlconn2.Open();
                    var mssqlDs2 = GetDataSet(mssqlconn2, DBType.MSSQL, "Select top 10 * from ACM_ApplicationHost;");

                    mssqlconn.Dispose();
                    mssqlconn2.Dispose();
                    //using (SqlConnection mssqlconn = new SqlConnection(mssqlConnStr))
                    //{
                    //    mssqlconn.Open();
                    //    var mssqlDs = GetDataSet(mssqlconn, DBType.MSSQL, "Select top 10 * from ACM_ApplicationHost;");
                    //}
                }
                catch (Exception e)
                {
                    throw;
                }
                finally
                {
                    scope.Dispose();
                }
            }
        }

        /// <summary>
        /// 测试分布式事务
        /// </summary>
        [TestMethod]
        public void TestMSDTC_MSSQL_MySQL()
        {
            //开启外部MSSQL事务
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    using (SqlConnection mssqlconn = new SqlConnection(mssqlConnStr))
                    {
                        mssqlconn.Open();
                        var mssqlDs = GetDataSet(mssqlconn, DBType.MSSQL, "Select top 10 * from ACM_ApplicationHost;");
                    }

                    using (MySqlConnection mysqlconn = new MySqlConnection(mysqlConnStr))
                    {
                        mysqlconn.Open();
                        var mysqlDs = GetDataSet(mysqlconn, DBType.MySQL, "Select * from Fas_dataobject limit 10");
                    }
                }
                catch (Exception e)
                {
                    throw;
                }
                finally
                {
                    scope.Dispose();
                }
            }
        }


        /// <summary>
        /// 测试分布式事务
        /// </summary>
        [TestMethod]
        public void TestMSDTC_MySQL_MySQL()
        {
            //开启外部MSSQL事务
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    MySqlConnection mysqlconn = new MySqlConnection(mysqlConnStr);
                    mysqlconn.Open();
                    var mysqlDs = GetDataSet(mysqlconn, DBType.MySQL, "Select * from Fas_dataobject limit 10");

                    MySqlConnection mysqlconn2 = new MySqlConnection(mysqlConnStr);
                    mysqlconn2.Open();
                    var mysqlDs2 = GetDataSet(mysqlconn2, DBType.MySQL, "Select * from Fas_dataobject limit 10");

                    mysqlconn.Dispose();
                    mysqlconn2.Dispose();

                    //using (MySqlConnection mysqlconn = new MySqlConnection(mysqlConnStr))
                    //{
                    //    mysqlconn.Open();
                    //    var mysqlDs = GetDataSet(mysqlconn, DBType.MySQL, "Select * from Fas_dataobject limit 10");
                    //}
                    scope.Complete();
                }
                catch (Exception e)
                {
                    throw;
                }
                finally
                {
                    scope.Dispose();
                }
            }
        }

        [TestMethod]
        public void Test()
        {
            try
            {
                //开启外部MSSQL事务
                using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        using (SqlConnection mssqlconn = new SqlConnection("Database=TMaster;Server=139.219.7.200,1433;User ID=root;Password=123456;"))
                        {
                            mssqlconn.Open();
                            var mssqlDs = GetDataSet(mssqlconn, DBType.MSSQL, "Select top 10 * from dep_userrequirement;");
                            //开启内部MySQL事务
                            using (TransactionScope scope2 = new TransactionScope())
                            {
                                try
                                {
                                    using (MySqlConnection mysqlconn = new MySqlConnection(mysqlConnStr))
                                    {
                                        mysqlconn.Open();
                                        var mysqlDs = GetDataSet(mysqlconn, DBType.MySQL, "Select * from Fas_dataobject limit 10");
                                    }
                                    scope2.Complete();
                                }
                                catch (Exception e)
                                {

                                    throw;
                                }
                                finally
                                {
                                    scope2.Dispose();
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                    finally
                    {
                        scope.Dispose();
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }

        [TestMethod]
        public void TestMSSQLQuery()
        {
            try
            {
                //开启外部MSSQL事务
                using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        using (SqlConnection mssqlconn = new SqlConnection("Database=TDEP;Server=139.219.7.200,1433;User ID=root;Password=123456;"))
                        {
                            mssqlconn.Open();
                            var mssqlDs = GetDataSet(mssqlconn, DBType.MSSQL, "Select top 10 * from DEP_UserRequirement;");
                        }
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                    finally
                    {
                        scope.Dispose();
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }



        #region Common Funcs
        public enum DBType
        {
            MySQL,
            MSSQL
        }

        private DataSet GetDataSet(IDbConnection conn, DBType dBType, string sql)
        {
            DbCommand command = default;
            DbDataAdapter adp = default;
            if (dBType == DBType.MySQL)
            {
                command = new MySqlCommand()
                {
                    Connection = conn as MySqlConnection,
                    CommandText = sql,
                };
                adp = new MySqlDataAdapter(command as MySqlCommand);
            }
            else if (dBType == DBType.MSSQL)
            {
                command = new SqlCommand()
                {
                    Connection = conn as SqlConnection,
                    CommandText = sql,
                };
                adp = new SqlDataAdapter(command as SqlCommand);
            }
            DataSet ds = new DataSet();
            adp.Fill(ds);
            return ds;
        }

        /// <summary>
        /// 注册配置
        /// </summary>
        public void RegistConfig()
        {
            T.ServiceComponent.Config.Client.LiveDebugService.Start();
            var key = Configkey;
            var value = localmssql;
            T.ServiceComponent.Config.Client.LiveDebugService.RegisterConfig(key, value);
        }

        /// <summary>
        /// 通过配置中心获取数据库服务
        /// </summary>
        /// <param name="configkey">配置key</param>
        /// <returns>数据库服务</returns>
        public ITDatabase GetDatabaseByConfigkey(string configkey = "")
        {
            try
            {
                return DatabaseHelper.GetDatabaseByConnectionKey(configkey);
                //return TAppContext.Current.GetInstance<ITDatabase>(configkey);
            }
            catch (Exception e)
            {
                throw new Exception($"配置串:{configkey}生成DB访问实例失败", e);
            }
        }

        #endregion
    }
}
